﻿using System;
using System.Collections.Generic;
using System.Collections;

namespace worldParser
{
    abstract class CGeometry : CWorldObject // Can be used as bounding object
    {
    }

    class CCone : CGeometry
    {
        float bottomRadius, height;
        bool side, bottom;
        public override void SetParamByName(Stack<IWorldStackObject> objstack, string param, List<string> values)
        {
            switch (param)
            {
                case "bottomRadius": bottomRadius = Float.Parse(values[0]); break;
                case "height": height = Float.Parse(values[0]); break;
                case "side": side = values[0][0] == 'T'; break;
                case "bottom": bottom = values[0][0] == 'T'; break;

                default: base.SetParamByName(objstack, param, values); break;
            }
        }
    }

    class CBox : CGeometry
    {
        Point3D size;
        public override void SetParamByName(Stack<IWorldStackObject> objstack, string param, List<string> values)
        {
            switch (param)
            {
                case "size": size = new Point3D(values); break;

                default: base.SetParamByName(objstack, param, values); break;
            }
        }
    }

    class CCylinder : CGeometry
    {
        bool bottom,side,top;
        float height,radius;
        int subdivision;

        public override void SetParamByName(Stack<IWorldStackObject> objstack, string param, List<string> values)
        {
            switch (param)
            {
                case "bottom": bottom = values[0][0] == 'T'; break;
                case "side": side = values[0][0] == 'T'; break;
                case "top": top = values[0][0] == 'T'; break;
                case "height": height = Float.Parse(values[0]); break;
                case "radius": radius = Float.Parse(values[0]); break;
                case "subdivision": subdivision = int.Parse(values[0]); break;

                default: base.SetParamByName(objstack, param, values); break;
            }
        }
    }

    class CSphere : CGeometry
    {
        float radius;
        int subdivision;
        public override void SetParamByName(Stack<IWorldStackObject> objstack, string param, List<string> values)
        {
            switch (param)
            {
                case "radius": radius = Float.Parse(values[0]); break;
                case "subdivision": subdivision = int.Parse(values[0]); break;
                default: base.SetParamByName(objstack, param, values); break;
            }
        }
    }

    class CIndexedFaceSet : CGeometry
    {
        CTextureCoordinate texCoord;
        bool ccw = true, solid = true, convex = true; 
        CCoordinate coord;
        CWorldArray coordIndex;
        float creaseAngle; 

        public override void SetParamByName(Stack<IWorldStackObject> objstack, string param, List<string> values)
        {
            switch (param)
            {
                case "creaseAngle": creaseAngle = Float.Parse(values[0]); break;
                case "ccw": ccw = values[0][0] == 'T'; break;
                case "solid": solid = values[0][0] == 'T'; break;
                case "convex": convex = values[0][0] == 'T'; break;
                case "coordIndex": coordIndex = new CWorldArray();
                    objstack.Push(coordIndex); break;
                default: base.SetParamByName(objstack, param, values); break;
            }
        }

        public override void PostParamByName(string param, IWorldStackObject value)
        {
            switch (param)
            {
                case "coord": coord = (CCoordinate)value; break;
                case "texCoord": texCoord = (CTextureCoordinate)value; break;
                default: base.PostParamByName(param, value); break;
            }
        }
    }
     
    class CElevationGrid : CGeometry
    {
        CColors color;
        CWorldArray height;
        bool colorPerVertex;
        float xDimension, xSpacing, zDimension, zSpacing;
        public override void SetParamByName(Stack<IWorldStackObject> objstack, string param, List<string> values)
        {
            switch (param)
            {
                case "color": color = new CColors(); objstack.Push(color); break;
                case "colorPerVertex": colorPerVertex = values[0][0] == 'T'; break;
                case "xDimension": xDimension = Float.Parse(values[0]); break;
                case "xSpacing": xSpacing = Float.Parse(values[0]); break;
                case "zDimension": zDimension = Float.Parse(values[0]); break;
                case "zSpacing": zSpacing = Float.Parse(values[0]); break;
                case "height": height = new CWorldArray();
                    objstack.Push(height); break;

                default: base.SetParamByName(objstack, param, values); break;
            }
        }

        public override void PostParamByName(string param, IWorldStackObject value)
        {
            switch (param)
            {
                case "color": color = (CColors)value; break;
                default: base.PostParamByName(param, value); break;
            }
        }

    }

    class CExtrusion : CGeometry {
        bool beginCap, convex, endCap;
        CWorldArray   crossSection;
        CWorldArray   spine;
        float   creaseAngle;

        public override void SetParamByName(Stack<IWorldStackObject> objstack, string param, List<string> values)
        {
            switch (param)
            {                

                case "beginCap": beginCap = values[0][0] == 'T'; break;
                case "endCap": endCap = values[0][0] == 'T'; break;
                case "convex": convex = values[0][0] == 'T'; break;
                case "creaseAngle": creaseAngle = Float.Parse(values[0]); break;

                case "crossSection": crossSection = new CWorldArray();
                    objstack.Push(crossSection); break;
                case "spine": spine = new CWorldArray();
                    objstack.Push(spine); break;

                default: base.SetParamByName(objstack, param, values); break;
            }
        }
    }

}
